﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Globalization;
using Microsoft.Xna.Framework.Content;

namespace XNAchievement.Achievements
{
    /// <summary>
    /// Represents a achievement, that is unlocked when the internal counter
    /// reaches a specific number. The counter can only be incremented or reset.
    /// Use for achievements like "kill five enemys without being hit" or
    /// "chop 300 trees". Can raises Notification events of type "Progressed".
    /// </summary>
    [Serializable]
    public class CounterAchievement : Achievement
    {
        /// <summary>
        /// Gets the current value of the counter.
        /// </summary>
        public float Counter { get; protected set; }

        /// <summary>
        /// Gets ot sets the value that unlocks the achievement
        /// when the counter reaches it.
        /// </summary>
        public float UnlockValue { get; set; }

        /// <summary>
        /// Every time the completion percentage reaches this interval a
        /// "Notification" event of the type "Progressed" is raised.
        /// Set to 0 to disable. Example: Setting this value to 0.1f will
        /// raise an event at 10%,20% etc. Use the "Progressing" event to
        /// cancel a Notification.
        /// </summary>
        public float NotificationInterval { get; set; }

        /// <summary>
        /// This event is fired when a Progressed Notification will be
        /// triggered. Set e.Cancel to true to cancel the notification.
        /// </summary>
        [field:NonSerialized]
        public event EventHandler<ProgressingEventArgs> Progressing;

        /// <summary>
        /// Creates a locked achievements with the given internal name, using the given texture names.
        /// If no image is needed pass null for the name.
        /// </summary>
        public CounterAchievement(string internalName, string lockedTextureName, string unlockedTextureName)
            : base(internalName, lockedTextureName, unlockedTextureName)
        {
        }

        /// <summary>
        /// For internal use only.
        /// </summary>
        protected CounterAchievement()
        {
        }

        /// <summary>
        /// Increases the counter by the given value.
        /// </summary>
        /// <param name="by">The amount to increase. Default: 1</param>
        public void IncreaseCounter(float by = 1)
        {
            Counter += by;

            if (Counter >= UnlockValue)
                Unlock();
            else if (NotificationInterval != 0 && (int)((Counter - by) / UnlockValue / NotificationInterval) != (int)(Counter / UnlockValue / NotificationInterval))
            {
                var e = new ProgressingEventArgs(Counter / UnlockValue);
                OnProgressing(e);

                if (!e.Cancel)
                    OnNotification(new NotificationEventArgs(NotificationType.Progressed, e.Amount));
            }
        }

        /// <summary>
        /// Resets the counter to zero.
        /// </summary>
        public void ResetCounter()
        {
            IncreaseCounter(-Counter); //Trigger the correct events.
        }
   
        /// <summary>
        /// Raises the "Progressing" event.
        /// </summary>
        protected virtual void OnProgressing(ProgressingEventArgs e)
        {
            if (Progressing != null)
                Progressing(this, e);
        }
    }
}
